package com.jn.util.tag;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.BodyTagSupport;

import com.jn.util.CodeUtil;

public class DictCodeSelectTag extends BodyTagSupport {

	private static final long serialVersionUID = -7146553047338820754L;
	private String codeType;
	private String clazz;
	private String style;
	private String attributes;
	private String name;
	private String value;
	private String ignores;
	private String firstLabel;
	private String firstValue;

	StringBuffer html = new StringBuffer();

	public int doStartTag() throws JspException {
		this.html = new StringBuffer("<select id=\"J_" + this.name
				+ "\" name=\"").append(this.name).append("\"");
		if (this.clazz != null)
			this.html.append(" class=\"").append(this.clazz).append("\"");
		if (this.style != null)
			this.html.append(" style=\"").append(this.style).append("\"");
		if (this.attributes != null)
			this.html.append(" ").append(map2Attr(getAttributesMap()));
		this.html.append(">");
		this.html.append(getOptions());

		return EVAL_BODY_INCLUDE;
	}

	public int doEndTag() throws JspException {
		this.html.append("</select>");
		write(this.pageContext, this.html.toString());
		this.html = null;
		return SKIP_BODY;
	}

	private String getOptions() {
		if (this.value == null)
			this.value = "";
		StringBuffer optionBuffer = new StringBuffer();
		if (this.firstLabel != null && this.firstValue != null)
			optionBuffer.append("<option value=\"" + this.firstValue + "\">"
					+ this.firstLabel + "</option>");
		else if (this.firstLabel != null)
			optionBuffer.append("<option value=\"\">" + this.firstLabel
					+ "</option>");
		Map<String, String> map = CodeUtil.getCodeMap(this.codeType);

		List<String> ignoreList = new ArrayList<String>();
		if (this.ignores != null) {
			String[] arr = this.ignores.split(",");
			for (String s : arr) {
				ignoreList.add(s);
			}
		}
		for (String key : map.keySet()) {
			if (ignoreList.contains(key))
				continue;
			optionBuffer.append("<option value=\"").append(key).append("\"");
			if (this.value.equals(key)) {
				optionBuffer.append(" selected=\"selected\"");
			}
			optionBuffer.append(">").append((String) map.get(key))
					.append("</option>");
		}
		return optionBuffer.toString();
	}

	public HashMap<String, String> getAttributesMap() {
		HashMap<String, String> map = attr2Map(getAttributes());
		if (this.style != null) {
			if (map == null)
				map = new HashMap<String, String>();
			map.put("style", this.style);
		}
		return map;
	}

	public void write(PageContext context, String html) throws JspException {
		JspWriter writer = context.getOut();
		try {
			writer.print(html);
		} catch (IOException e) {
			e.printStackTrace();
			throw new JspException(e);
		}
	}

	public static HashMap<String, String> attr2Map(String attributes) {
		HashMap<String, String> map = null;

		if (attributes != null) {
			map = new HashMap<String, String>();
			String[] atts = attributes.split(";");
			if (atts != null) {
				for (int i = 0; i < atts.length; ++i) {
					String[] att = atts[i].split("=");
					if ((att != null) && (att.length == 2)) {
						map.put(att[0], att[1]);
					}
				}
			}
		}
		return map;
	}

	public static String map2Attr(HashMap<String, String> attrs) {
		StringBuffer html = new StringBuffer("");
		if (attrs != null) {
			for (Iterator<Map.Entry<String, String>> it = attrs.entrySet()
					.iterator(); it.hasNext();) {
				Map.Entry<String, String> entry = it.next();
				html.append(entry.getKey().toString() + "=\""
						+ entry.getValue().toString() + "\" ");
			}
		}

		return html.toString();
	}

	public String getCodeType() {
		return codeType;
	}

	public void setCodeType(String codeType) {
		this.codeType = codeType;
	}

	public String getClazz() {
		return clazz;
	}

	public void setClazz(String clazz) {
		this.clazz = clazz;
	}

	public String getStyle() {
		return style;
	}

	public void setStyle(String style) {
		this.style = style;
	}

	public String getAttributes() {
		return attributes;
	}

	public void setAttributes(String attributes) {
		this.attributes = attributes;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}

	public String getIgnores() {
		return ignores;
	}

	public void setIgnores(String ignores) {
		this.ignores = ignores;
	}

	public String getFirstLabel() {
		return firstLabel;
	}

	public void setFirstLabel(String firstLabel) {
		this.firstLabel = firstLabel;
	}

	public String getFirstValue() {
		return firstValue;
	}

	public void setFirstValue(String firstValue) {
		this.firstValue = firstValue;
	}

}
